package com.gaojx.lang.util;

import com.gaojx.lang.annotation.SDKComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author junxiang.gao
 * @since 2020/9/1
 */
public class ClassScanUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClassScanUtil.class);

    /**
     * 获取bean名称 bean类型一一对应的Map集合
     *
     * @param packageName 需要扫描的包名
     * @return map
     * @throws ClassNotFoundException 找不到类
     */
    public static Map<String, Class<?>> getBeans(String packageName) throws ClassNotFoundException {
        // 将包名转换为路径格式
        List<String> strList = Arrays.asList(packageName.split("\\."));

        StringBuilder stringBuilder = new StringBuilder();

        strList.forEach(item -> {
            stringBuilder.append(item).append("/");
        });

        // 当前包的绝对路径
        String file = Thread.currentThread().getContextClassLoader()
                .getResource(stringBuilder.toString().substring(0, stringBuilder.length() - 1))
                .getFile();

        Map<String, Class<?>> classMap = new HashMap<>();

        // 递归获取Class文件
        getAllClassList(packageName, file, classMap);
        return classMap.isEmpty() ? null : classMap;
    }

    /**
     * 递归加载目录下的class文件
     *
     * @param packageName 包名
     * @param path        文件路径
     * @param classMap    存储Map
     */
    public static void getAllClassList(String packageName, String path, Map<String, Class<?>> classMap)
            throws ClassNotFoundException {
        File files = new File(path);
        File[] fileList = files.listFiles();

        for (File file : fileList) {
            if (file.isDirectory()) {
                String currentPackage = packageName + "." + file.getName();
                getAllClassList(currentPackage, file.getAbsolutePath(), classMap);
            }
            if (file.getName().endsWith(".class")) {
                String name = file.getName();
                String fileName = name.substring(0, name.indexOf("."));
                String currentPackage = packageName + "." + name.substring(0, name.indexOf("."));
                Class<?> forName = Class.forName(currentPackage);

                if (forName.isAnnotationPresent(SDKComponent.class)) {
                    LOGGER.info("读取到需要注入的类: =========>{}", currentPackage);
                    classMap.put(initialsToLowerCase(fileName), forName);
                }
            }
        }
    }

    private static String initialsToLowerCase(String fileName){
        char[] chars = fileName.toCharArray();
        if (chars[0] >= 65 && chars[0] <=90){
            chars[0] += 32;
        }
        return String.valueOf(chars);
    }
}
